package pers.vic.basics.leetcode;

import java.util.*;

/**
 * @author Vic.xu
 * @description: 18. 四数之和
 * @date: 2020/11/11 8:28
 * @see J0015_M_ThreeSum 参见三数之和  依然是双指针
 */
public class J0018_M_FourSum {
    /*
    给定一个包含 n 个整数的数组 nums 和一个目标值 target，判断 nums 中是否存在四个元素 a，b，c 和 d ，
    使得 a + b + c + d 的值与 target 相等？找出所有满足条件且不重复的四元组。
    注意：答案中不可以包含重复的四元组。
     */

    /**
     * 果然熟能生巧   这一次 闭着眼睛默写 一遍通过了
     */
    public static List<List<Integer>> fourSum(int[] nums, int target) {
        if (nums == null || nums.length < 4) {
            return new ArrayList<>();
        }
        Arrays.sort(nums);
        Set<List<Integer>> result = new HashSet<>();
        int len = nums.length;

        for (int i = 0; i < len - 3; i++) {
            for (int j = i + 1; j < len - 2; j++) {
                //变成了两数之和
                int twoNum = target - nums[i] - nums[j];
                int l = j + 1;
                int r = len - 1;
                while (l < r) {
                    int sum = nums[l] + nums[r];
                    if (sum < twoNum) {
                        l++;
                    } else if (sum > twoNum) {
                        r--;
                    } else {
                        result.add(Arrays.asList(nums[i], nums[j], nums[l], nums[r]));
                        l++;
                        r--;
                    }
                }
            }
        }
        return new ArrayList<>(result);
    }

    /*
     nums = [1, 0, -1, 0, -2, 2]，和 target = 0。

    满足要求的四元组集合为：
    [
      [-1,  0, 0, 1],
      [-2, -1, 1, 2],
      [-2,  0, 0, 2]
    ]
     */
    public static void main(String[] args) {
        int[] nums = {1, 0, -1, 0, -2, 2};
        int target = 0;
        fourSum(nums, target).forEach(System.out::println);

    }
}
